package com.imooc.animation360.engine;

import java.lang.reflect.Field;

import com.imooc.animation360.view.FloatCircleView;
import com.imooc.animation360.view.FloatMenuView;

import android.content.Context;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;

public class FloatViewManager {
	private static FloatViewManager instance;
	private Context context;
	private FloatCircleView circleVeiw;
	private FloatMenuView floatMenuView;
	private WindowManager mWindowManager; // 通过WindowManager操作浮窗体的显示,隐藏等.
	private WindowManager.LayoutParams params;
	private float startX;
	private float startY;
	private float x0;
	private float y0;
	private OnTouchListener circleViweTouchListener = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				startX = event.getRawX();
				startY = event.getRawY();
				x0 = event.getRawX();
				y0 = event.getRawY();
				break;
			case MotionEvent.ACTION_MOVE:
				float x = event.getRawX();
				float y = event.getRawY();
				float dx = x - startX;
				float dy = y - startY;
				params.x += dx;
				params.y += dy;
				circleVeiw.setDragState(true); // 更新拖拽状态.
				mWindowManager.updateViewLayout(circleVeiw, params);
				startX = x;
				startY = y;
				break;
			case MotionEvent.ACTION_UP:
				// 手指离开的时候回到手机屏幕中线的左边缘或右边缘.
				int[] screenSize = getScreenSize();
				int screenWidth = screenSize[0];
				float x1 = event.getRawX();

				if (x1 < screenWidth / 2) {
					params.x = 0;
				} else {
					params.x = screenWidth - circleVeiw.width;
				}
				circleVeiw.setDragState(false);// 更新拖拽状态.
				mWindowManager.updateViewLayout(circleVeiw, params);

				// 如果x方向的变化量大于5个像素则认为是拖拽事件,否则就点击事件.
				if (Math.abs(x1 - x0) > 5) {
					return true;
				} else {
					return false;
				}
			default:
				break;
			}
			return false;
		}
	};

	private OnClickListener circleViewClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// 1.隐藏circleView; 2.显示菜单栏; 3.开启动画.
			mWindowManager.removeView(circleVeiw);
			showFloatMenuView();
			floatMenuView.startAnimation();
		}
	};

	private FloatViewManager(Context context) {
		this.context = context;
		mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		circleVeiw = new FloatCircleView(context);
		floatMenuView = new FloatMenuView(context);
		circleVeiw.setOnTouchListener(circleViweTouchListener);
		circleVeiw.setOnClickListener(circleViewClickListener);
	}

	public static FloatViewManager getInstance(Context context) {
		if (instance == null) {
			synchronized (FloatViewManager.class) {
				if (instance == null) {
					instance = new FloatViewManager(context);
				}
			}
		}
		return instance;
	}

	/**
	 * 获取手机屏幕尺寸.
	 * 
	 * @return
	 */
	public int[] getScreenSize() {
		int[] size = new int[2];
		DisplayMetrics outMetrics = new DisplayMetrics();
		mWindowManager.getDefaultDisplay().getMetrics(outMetrics);
		size[0] = outMetrics.widthPixels;
		size[1] = outMetrics.heightPixels;
		return size;
	}

	
	/**
	 * 获取状态栏的高度. 
	 * 通过反射获取android隐藏的R.java文件,然后获取里边内部类Dimen里的字段.
	 * @return
	 */
	private int getStatusBarHeight() {
		try {
			Class clazz = Class.forName("com.android.internal.R$dimen");
			Field field = clazz.getField("status_bar_height");
			Integer statusBarId = (Integer) field.get(clazz.newInstance());
			int statusBarHeight = context.getResources().getDimensionPixelSize(statusBarId);
			return statusBarHeight;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * 显示浮窗小球的方法.
	 */
	public void showFloatCircleView() {
		if(params==null){
			params = new WindowManager.LayoutParams();
			// 宽高
			params.width = circleVeiw.width;
			params.height = circleVeiw.height;
			// 相对位置
			params.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT;
			// x,y偏移量
			params.x = 0;
			params.y = 0;
			// 显示类型(Phone级别已经很高了,但是我们要优于电话级别)
			params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
//			params.type = WindowManager.LayoutParams.TYPE_TOAST;
			// 浮窗体小球不与其它控件抢焦点.
			params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
			// 设置背景为透明.
			// params.format = PixelFormat.TRANSLUCENT;// 半透明
			params.format = PixelFormat.RGBA_8888;
		}
		
		mWindowManager.addView(circleVeiw, params);
	}

	/**
	 * 显示浮窗体菜单栏的方法.
	 */
	private void showFloatMenuView() {
		WindowManager.LayoutParams params = new WindowManager.LayoutParams();
		// 宽高
		params.width = getScreenSize()[0]; 							//屏幕宽度
		params.height = getScreenSize()[1]-getStatusBarHeight();	//屏幕高度-状态栏高度.
		// 相对位置
		params.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT;
		// x,y偏移量
		params.x = 0;
		params.y = 0;
		// 显示类型(Phone级别已经很高了,但是我们要优于电话级别)
		params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
		// 浮窗体小球不与其它控件抢焦点.
		params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
		// 设置背景为透明.
		// params.format = PixelFormat.TRANSLUCENT;// 半透明
		params.format = PixelFormat.RGBA_8888;
		mWindowManager.addView(floatMenuView, params);
	}

	/**
	 * 隐藏底部菜单.
	 */
	public void hideFloatMenuView() {
		mWindowManager.removeView(floatMenuView);
	}

}
